home *** CD-ROM | disk | FTP | other *** search
/ PC Media 22 / PC MEDIA CD22.iso / share / prog / spm220e / starintf.pas < prev    next >
Pascal/Delphi Source File  |  1995-10-08  |  38KB  |  1,636 lines

  1. {
  2. ╔═════════════════════════════════════════════════════════════════════════════╗
  3. ║ NAME      : STARINTF.PAS                                                    ║
  4. ║ FUNCTION  : Interfacing functions and procedures for the serial driver      ║
  5. ║           : STARCOMM.EXE. PASCAL Language listing for STARCOMM used as a    ║
  6. ║           : simple T.S.R. BIOS, or as a DOS DEVICE DRIVER, or as a library. ║
  7. ║ VERSION   : 2.20                                                            ║
  8. ║ LANGUAGE  : TURBO PASCAL v4.0 and laters (Developed as a "UNIT"...).        ║
  9. ║ REMARKS   : If an application program calls the functions to access the     ║
  10. ║           : serial ports whereas "RS_accessible=FALSE" (or "COMM_ouvert=    ║
  11. ║           : FALSE" for the DEVICE DRIVER interfacing), the returned codes   ║
  12. ║           : won't have ANY MEANING... These calls to the driver won't have  ║
  13. ║           : any effect in such a case.                                      ║
  14. ║           : In order to use the "library" mode, ativate the lines labeled   ║
  15. ║           : "--- LIBRARY ---"...                                            ║
  16. ║           : Please, report yourself to STAR_REF.DOC to get any information  ║
  17. ║           : you need on these procedures...                                 ║
  18. ║ COPYRIGHT : HETRU Fabrice 1991-1995.                                        ║
  19. ╚═════════════════════════════════════════════════════════════════════════════╝
  20. }
  21.  
  22.  
  23.  
  24. UNIT StarIntf;
  25.  
  26.  
  27.  
  28. interface
  29.  
  30. USES Dos;
  31.  
  32. (* --- LIBRARY --- *)
  33. (* To use the "library" mode of STARCOMM, activate the  *)
  34. (* following line:                                      *)
  35. (*   {$L SCLIB.OBJ}                                     *)
  36. (* --------------- *)
  37.  
  38. TYPE
  39.   Chn4octets = STRING[4] ;
  40.  
  41. CONST
  42.   (* Serial port to be managed by the called function: 0 (COM1:)...7 (COM8:) *)
  43.   CommPort : WORD = 0 ;
  44.   (* Array to store which serial ports are acknowledged, and which are NOT. *)
  45.   (* This array is up-dated from the "Port_Opened" routine.                 *)
  46.   ComExist : ARRAY[0..7] OF BOOLEAN=(TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE);
  47.   (* 8250 basics adresses for the COM1 to COM4 serial ports ? *)
  48.   BasePort1 : WORD = $3F8;
  49.   BasePort2 : WORD = $2F8;
  50.   BasePort3 : WORD = $3E8;
  51.   BasePort4 : WORD = $2E8;
  52.   (* Possibles values for the hard hand-shaking activating flag. *)
  53.   RTS_CTS  : BYTE = 1;
  54.   DTR_DSR  : BYTE = 2;
  55.   BothCmde : BYTE = 3;
  56.   RI       : BYTE = 4;
  57.   DCD      : BYTE = 5;
  58.   OUT1     : BYTE = 6;
  59.   (* Possibles values for the hard hand-shaking working mode flag. *)
  60.   Inactif   : BYTE =  0;
  61.   Local     : BYTE = 76; (*'L'*)
  62.   Eloigne   : BYTE = 69; (*'E'*)
  63.   Bilateral : BYTE = 66; (*'B'*)
  64.   (* Codes to be used as soft hand-shaking control signals. *)
  65.   Xon  : BYTE = $11;
  66.   Xoff : BYTE = $13;
  67.   (* Possibles values for the errors substitution process working mode.      *)
  68.   NonActif : BYTE = 0; (* Smode0: Erroneous bytes will be stored in the      *)
  69.                        (* receiving buffer exactly as they are decoded.      *)
  70.   Remplace : BYTE = 1; (* Smode1: U/S bytes are subtitued with special code. *)
  71.   RempNULL : BYTE = 2; (* Smode2: U/S bytes are lost. The lost bytes counter *)
  72.                        (* is incremented for each erroneous byte lost.       *)
  73.   NoBreakBuff : BYTE = 100; (* Bmode0: Pas de code de BREAK en buffer de rcp *)
  74.   BreakOnBuff : BYTE = 200; (* Bmode1: Code spécial de BREAK voulu en rcp... *)
  75.   (* DEVICE DRIVER name associated with STARCOMM.EXE. *)
  76.   NomDevice : STRING[8] = 'COMM    ';
  77.   (* Computer architectural type (used for the IRQs authorizations...). *)
  78.   Type_PC : BYTE = 1;
  79.   Type_XT : BYTE = 2;
  80.   Type_AT : BYTE = 3;
  81.   PS2_PC  : BYTE = 4;
  82.   PS2_AT  : BYTE = 5;
  83.  
  84. VAR
  85.   RS_accessible : BOOLEAN ; (* TRUE=Driver in RAM, FALSE=Driver NOT in RAM *)
  86.   type_driver   : BYTE    ; (* 0=Not here,1= BIOS mode, 2= DEV-DRV mode.   *)
  87.   handler_voie_serie : WORD ;  (* "COMM" File handler.                     *)
  88.   COMM_ouvert   : BOOLEAN ; (* File status flag for the "COMM" dev. driver.*)
  89.   Serial_error  : WORD    ; (* DOS error code received at the opening...   *)
  90.  
  91. (* --- LIBRARY --- *)
  92. (* To use the "library" mode of STARCOMM, activate the  *)
  93. (* following procedures:                                *)
  94. (*  PROCEDURE Set_SCL;                                  *)
  95. (*  PROCEDURE UnSetSCL;                                 *)
  96. (*  PROCEDURE SCLservs;                                 *)
  97. (* --------------- *)
  98. (* Functions to be reached using the interrupt 14h. *)
  99. PROCEDURE Version(VAR NumVer: Chn4octets);
  100. FUNCTION  Open_Port: BYTE;
  101. FUNCTION  OpenPort_Buff(Segment,Offset,Taille_in,Taille_out: WORD): BYTE;
  102. FUNCTION  Close_Port(ProtegeBuff: BOOLEAN): BYTE;
  103. FUNCTION  Port_Opened: BOOLEAN;
  104. FUNCTION  Interdit_Port: BYTE;
  105. FUNCTION  Autorise_Port: BYTE;
  106. FUNCTION  EtatVerrouilleComm(VAR Mode: BYTE): BYTE;
  107. FUNCTION  VerrouilleComm(Mode: BYTE): BYTE;
  108. FUNCTION  SLOW_Ems: BYTE;
  109. FUNCTION  FAST_Ems: BYTE;
  110. FUNCTION  Send_SLOW: BOOLEAN;
  111. PROCEDURE Get_Ports_Adresses;
  112. FUNCTION  Infos_Uart(VAR Uart_type: BYTE; VAR Uart_adresse: WORD;
  113.           VAR Irq,FIFO_actif,Taille_FIFO: BYTE): BYTE;
  114. FUNCTION  Set_New_Uart(Uart_adresse: WORD;
  115.           Irq,FIFO_actif,Taille_FIFO: BYTE): BYTE;
  116. PROCEDURE Infos_Buffs(VAR Nb_actifs, Nb_maxi: BYTE;
  117.           VAR Taille_InBuff,Taille_OutBuff: WORD);
  118. FUNCTION  Init_Port(longueur, stop_bit, parity: CHAR; vitesse: LONGINT;
  119.           VAR Taille_InBuff: WORD; VAR Taille_OutBuff: WORD): BYTE;
  120. PROCEDURE Init_status(VAR Format: WORD);
  121. FUNCTION  Reset_Init_status(Format: WORD): BYTE;
  122. PROCEDURE Flush_buffers;
  123. PROCEDURE Flush_InBuff;
  124. PROCEDURE Flush_OutBuff;
  125. PROCEDURE ResetPort_and_TimMAX(RdTim_MAX: BYTE; VAR Old_RdTim_MAX: BYTE;
  126.           WrTim_MAX: BYTE; VAR Old_WrTim_MAX: BYTE);
  127. PROCEDURE Status_Trait_Erreurs(VAR mode: BYTE; VAR codeEr, codeBk: CHAR);
  128. FUNCTION  Def_Trait_Erreurs(mode: BYTE; code: CHAR): BYTE;
  129. FUNCTION  Change_com_port(Num_port: BYTE): BYTE;
  130. FUNCTION  Attend_Buff_ems_vide(Temps_maxi: BYTE): BOOLEAN;
  131. FUNCTION  CheckBufferIn(VAR nb_a_lire: WORD): BOOLEAN;
  132. FUNCTION  CheckBufferOut(VAR place_libre: WORD): BOOLEAN;
  133. FUNCTION  ReadSerie(VAR c: CHAR; nombre: WORD; VAR Nb_received: WORD): BYTE;
  134. FUNCTION  WriteSerie(VAR c: CHAR; nombre: WORD; VAR Nb_written: WORD): BYTE;
  135. FUNCTION  ReadCarSerie(VAR c: CHAR): BYTE;
  136. FUNCTION  WriteCarSerie(c: CHAR): BYTE;
  137. FUNCTION  Peek_rcp(VAR c: CHAR): BYTE;
  138. FUNCTION  Poke_rcp(c: CHAR): BYTE;
  139. FUNCTION  WriteCmde(VAR Cmde: CHAR; nombre: BYTE; UseDTR: BOOLEAN): BYTE;
  140. PROCEDURE Etat_du_Modem(VAR Voie_active: CHAR; VAR Pret, Clear_to_send,
  141.           Sonnerie, Porteuse, Changements: BOOLEAN; VAR deltaDSR, deltaCTS,
  142.           deltaRI, deltaDCD: BYTE);
  143. PROCEDURE Set_DTR;
  144. PROCEDURE Clear_DTR;
  145. PROCEDURE Set_RTS;
  146. PROCEDURE Clear_RTS;
  147. PROCEDURE Set_OUT1;
  148. PROCEDURE Clear_OUT1;
  149. PROCEDURE Send_break(duree: BYTE);
  150. FUNCTION  Errors_Report(VAR Buff_overflow, Engorgement, Parite, Stop_bit,
  151.           Break_it: BYTE): BOOLEAN;
  152. FUNCTION  Port_Free: BOOLEAN;
  153. FUNCTION  HandShake_Status(Proto_type: BYTE;VAR SendEnabled: BOOLEAN): BYTE;
  154. PROCEDURE HandShake_Setup(Proto_type: BYTE; state: BYTE);
  155. FUNCTION  XonoffShaking_Status(VAR SendEnabled: BOOLEAN;
  156.           VAR Nb_Xoff: BYTE): BYTE;
  157. PROCEDURE XonoffShaking_Setup(state: BYTE);
  158. PROCEDURE Set_routine(VAR Utilise: BOOLEAN; VAR Segment,Offset: WORD);
  159. PROCEDURE Reset_routine(Segment,Offset: WORD);
  160. PROCEDURE Unset_routine;
  161. PROCEDURE Set_err_routine(VAR Utilise: BOOLEAN; VAR Segment,Offset: WORD);
  162. PROCEDURE Reset_err_routine(Segment,Offset: WORD);
  163. PROCEDURE Unset_err_routine;
  164. PROCEDURE Verrouille;
  165. PROCEDURE Deverrouille;
  166. FUNCTION  GetDeviceName: BYTE;
  167. FUNCTION  GetPortDevice: BYTE;
  168. FUNCTION  ResetPortDevice: BYTE;
  169. FUNCTION  EmulBIOS: BOOLEAN;
  170. PROCEDURE SetEmulBIOS(status: BOOLEAN);
  171. FUNCTION  OrdiType: BYTE;
  172. PROCEDURE SetOrdiType(OrdiType: BYTE);
  173. (* Functions to be reached using the DOS interrupt 21h (DEVICE DRIVER mode). *)
  174. FUNCTION  Open_COMM: WORD;
  175. FUNCTION  Close_COMM: INTEGER;
  176. FUNCTION  IOStream_READ(VAR Voie_active: CHAR;VAR Format: WORD; VAR RTS_type,
  177.           DTR_type, RI_type, DCD_type, OUT1_type, Xonoff_type: CHAR): BOOLEAN;
  178. FUNCTION  IOStream_WRITE(VAR Voie_active: CHAR;VAR Format: WORD; VAR RTS_type,
  179.           DTR_type, RI_type, DCD_type, OUT1_type, Xonoff_type: CHAR): BOOLEAN;
  180. FUNCTION  CheckCOMMIn: BOOLEAN;
  181. FUNCTION  CheckCOMMOut: BOOLEAN;
  182. FUNCTION  ReadCOMM(VAR c: CHAR; nombre: WORD): INTEGER;
  183. FUNCTION  WriteCOMM(VAR c: CHAR; nombre: WORD): INTEGER;
  184. (* Function to scan STARCOMM.EXE in memory. *)
  185. FUNCTION  Check_STARCOMM_Present: BYTE;
  186.  
  187.  
  188.  
  189. implementation
  190.  
  191. VAR
  192.   reg88 : Registers ;
  193.  
  194.  
  195. (* --- LIBRARY --- *)
  196. (* To use the "library" mode of STARCOMM, activate the  *)
  197. (* following procedures:                                *)
  198. (*                                                      *)
  199. (*  PROCEDURE Set_SCL; External;                        *)
  200. (*                                                      *)
  201. (*  PROCEDURE UnSetSCL; External;                       *)
  202. (*                                                      *)
  203. (*  PROCEDURE SCLservs; External;                       *)
  204. (* --------------- *)
  205.  
  206.  
  207. PROCEDURE Version(VAR NumVer: Chn4octets);
  208. BEGIN
  209.   IF RS_accessible THEN
  210.   BEGIN
  211.     WITH reg88 DO
  212.     BEGIN
  213.       ah := 6;
  214.       Intr($14,Dos.Registers(reg88));
  215.       NumVer[1] := chr(al);
  216.       NumVer[2] := '.';
  217.       ax := di;
  218.       NumVer[3] := chr(ah);
  219.       NumVer[4] := chr(al)
  220.     END;
  221.     NumVer[0] := chr(4);
  222.   END
  223.   ELSE NumVer[0] := chr(0);
  224. END;
  225.  
  226.  
  227. FUNCTION Open_Port: BYTE;
  228. BEGIN
  229.   IF RS_accessible THEN
  230.   BEGIN
  231.     WITH reg88 DO
  232.     BEGIN
  233.       ah := $07;
  234.       al := 0;
  235.       dx := CommPort;
  236.       Intr($14,Dos.Registers(reg88));
  237.       Open_Port := ah
  238.     END;
  239.   END
  240. END;
  241.  
  242.  
  243. FUNCTION OpenPort_Buff(Segment,Offset,Taille_in,Taille_out: WORD): BYTE;
  244. BEGIN
  245.   IF RS_accessible THEN
  246.   BEGIN
  247.     WITH reg88 DO
  248.     BEGIN
  249.       ah := $07;
  250.       al := 6;
  251.       dx := CommPort;
  252.       es := Segment;
  253.       di := Offset;
  254.       bx := Taille_in;
  255.       cx := Taille_out;
  256.       Intr($14,Dos.Registers(reg88));
  257.       OpenPort_Buff := ah
  258.     END;
  259.   END
  260. END;
  261.  
  262.  
  263. FUNCTION Close_Port(ProtegeBuff: BOOLEAN): BYTE;
  264. BEGIN
  265.   IF RS_accessible THEN
  266.   BEGIN
  267.     WITH reg88 DO
  268.     BEGIN
  269.       ah := $07;
  270.       IF ProtegeBuff THEN al := 1 ELSE al := 7;
  271.       dx := CommPort;
  272.       Intr($14,Dos.Registers(reg88));
  273.       Close_Port := ah
  274.     END;
  275.   END
  276. END;
  277.  
  278.  
  279. FUNCTION Port_Opened: BOOLEAN;
  280. BEGIN
  281.   IF RS_accessible THEN
  282.   BEGIN
  283.     WITH reg88 DO
  284.     BEGIN
  285.       ah := $07;
  286.       al := 2;
  287.       dx := CommPort;
  288.       Intr($14,Dos.Registers(reg88));
  289.       IF CommPort<8 THEN
  290.       BEGIN
  291.         IF ah=5 THEN ComExist[CommPort] := FALSE
  292.           ELSE ComExist[CommPort] := TRUE
  293.       END;
  294.       IF al=1 THEN Port_Opened := TRUE
  295.         ELSE Port_Opened := FALSE
  296.     END;
  297.   END
  298. END;
  299.  
  300.  
  301. FUNCTION Interdit_Port: BYTE;
  302. BEGIN
  303.   IF RS_accessible THEN
  304.   BEGIN
  305.     WITH reg88 DO
  306.     BEGIN
  307.       ah := $0A;
  308.       al := 0;
  309.       dx := CommPort;
  310.       Intr($14,Dos.Registers(reg88));
  311.       Interdit_Port := ah
  312.     END;
  313.   END
  314. END;
  315.  
  316.  
  317. FUNCTION Autorise_Port: BYTE;
  318. BEGIN
  319.   IF RS_accessible THEN
  320.   BEGIN
  321.     WITH reg88 DO
  322.     BEGIN
  323.       ah := $0A;
  324.       al := 1;
  325.       dx := CommPort;
  326.       Intr($14,Dos.Registers(reg88));
  327.       Autorise_Port := ah
  328.     END;
  329.   END
  330. END;
  331.  
  332.  
  333. FUNCTION EtatVerrouilleComm(VAR Mode: BYTE): BYTE;
  334. BEGIN
  335.   IF RS_accessible THEN
  336.   BEGIN
  337.     WITH reg88 DO
  338.     BEGIN
  339.       ah := $0A;
  340.       al := 6;
  341.       dx := CommPort;
  342.       Intr($14,Dos.Registers(reg88));
  343.       Mode := al;
  344.       EtatVerrouilleComm := ah
  345.     END;
  346.   END
  347. END;
  348.  
  349.  
  350. FUNCTION VerrouilleComm(Mode: BYTE): BYTE;
  351. BEGIN
  352.   IF RS_accessible THEN
  353.   BEGIN
  354.     WITH reg88 DO
  355.     BEGIN
  356.       ah := $0A;
  357.       al := Mode;
  358.       dx := CommPort;
  359.       Intr($14,Dos.Registers(reg88));
  360.       VerrouilleComm := ah
  361.     END;
  362.   END
  363. END;
  364.  
  365.  
  366. FUNCTION SLOW_Ems: BYTE;
  367. BEGIN
  368.   IF RS_accessible THEN
  369.   BEGIN
  370.     WITH reg88 DO
  371.     BEGIN
  372.       ah := $07;
  373.       al := 3;
  374.       dx := CommPort;
  375.       Intr($14,Dos.Registers(reg88));
  376.       SLOW_Ems := ah
  377.     END;
  378.   END
  379. END;
  380.  
  381.  
  382. FUNCTION FAST_Ems: BYTE;
  383. BEGIN
  384.   IF RS_accessible THEN
  385.   BEGIN
  386.     WITH reg88 DO
  387.     BEGIN
  388.       ah := $07;
  389.       al := 4;
  390.       dx := CommPort;
  391.       Intr($14,Dos.Registers(reg88));
  392.       FAST_Ems := ah
  393.     END;
  394.   END
  395. END;
  396.  
  397.  
  398. FUNCTION Send_SLOW: BOOLEAN;
  399. BEGIN
  400.   IF RS_accessible THEN
  401.   BEGIN
  402.     WITH reg88 DO
  403.     BEGIN
  404.       ah := $07;
  405.       al := 5;
  406.       dx := CommPort;
  407.       Intr($14,Dos.Registers(reg88));
  408.       IF al=1 THEN Send_SLOW := TRUE
  409.         ELSE Send_SLOW := FALSE
  410.     END;
  411.   END
  412. END;
  413.  
  414.  
  415. PROCEDURE Get_Ports_Adresses;
  416. BEGIN
  417.   BasePort1 := MEMW[$40:$00];
  418.   BasePort2 := MEMW[$40:$02];
  419.   BasePort3 := MEMW[$40:$04];
  420.   BasePort4 := MEMW[$40:$06]
  421. END;
  422.  
  423.  
  424. FUNCTION Infos_Uart(VAR Uart_type: BYTE; VAR Uart_adresse: WORD;
  425.               VAR Irq,FIFO_actif,Taille_FIFO: BYTE): BYTE;
  426. BEGIN
  427.   IF RS_accessible THEN
  428.   BEGIN
  429.     reg88.ah := $09;
  430.     reg88.al := 0;
  431.     reg88.dx := CommPort;
  432.     Intr($14,Dos.Registers(reg88));
  433.     Uart_type := reg88.al;
  434.     Uart_adresse := reg88.bx;
  435.     Irq := reg88.ch;
  436.     IF reg88.cl=0 THEN
  437.     BEGIN
  438.       FIFO_actif := 0;
  439.       Taille_FIFO := 1;
  440.     END
  441.     ELSE
  442.     BEGIN
  443.       FIFO_actif := 1;
  444.       Taille_FIFO := reg88.cl
  445.     END;
  446.     Infos_Uart := reg88.ah;
  447.   END
  448. END;
  449.  
  450.  
  451. FUNCTION Set_New_Uart(Uart_adresse: WORD;
  452.               Irq,FIFO_actif,Taille_FIFO: BYTE): BYTE;
  453. BEGIN
  454.   IF RS_accessible THEN
  455.   BEGIN
  456.     reg88.ah := $09;
  457.     reg88.al := 1;
  458.     reg88.dx := CommPort;
  459.     reg88.bx := Uart_adresse;
  460.     reg88.ch := Irq;
  461.     IF FIFO_actif=1 THEN reg88.cl := Taille_FIFO
  462.       ELSE reg88.cl := 0;
  463.     Intr($14,Dos.Registers(reg88));
  464.     Set_New_Uart := reg88.ah;
  465.   END
  466. END;
  467.  
  468.  
  469. PROCEDURE Infos_Buffs(VAR Nb_actifs, Nb_maxi: BYTE;
  470.               VAR Taille_InBuff,Taille_OutBuff: WORD);
  471. BEGIN
  472.   IF RS_accessible THEN
  473.   BEGIN
  474.     reg88.ah := $0D;
  475.     Intr($14,Dos.Registers(reg88));
  476.     Taille_InBuff := reg88.bx;
  477.     Taille_OutBuff := reg88.cx;
  478.     Nb_actifs := reg88.dh;
  479.     Nb_maxi := reg88.dl;
  480.   END
  481. END;
  482.  
  483.  
  484. FUNCTION Init_Port(longueur, stop_bit, parity: CHAR; vitesse: LONGINT;
  485.               VAR Taille_InBuff: WORD; VAR Taille_OutBuff: WORD): BYTE;
  486. VAR
  487.   descripteur_format, vitess : BYTE ;
  488. BEGIN
  489.   Init_Port := 1;
  490.   WITH reg88 DO
  491.   BEGIN
  492.     CASE longueur OF
  493.       '5': descripteur_format := $00;
  494.       '6': descripteur_format := $01;
  495.       '7': descripteur_format := $02;
  496.       '8': descripteur_format := $03;
  497.       ELSE Exit
  498.     END;
  499.     CASE stop_bit OF
  500.       '1': ;
  501.       '2': descripteur_format := descripteur_format + $04;
  502.       ELSE Exit
  503.     END;
  504.     CASE upcase(parity) OF
  505.       'N': ;
  506.       'I': descripteur_format := descripteur_format + 8;
  507.       'P': descripteur_format := descripteur_format + 24;
  508.       'T': descripteur_format := descripteur_format + 40;
  509.       'R': descripteur_format := descripteur_format + 56;
  510.       ELSE Exit
  511.     END;
  512.     IF vitesse=110 THEN vitess := 0
  513.       ELSE IF vitesse=150 THEN vitess := 1
  514.       ELSE IF vitesse=300 THEN vitess := 2
  515.       ELSE IF vitesse=600 THEN vitess := 3
  516.       ELSE IF vitesse=1200 THEN vitess := 4
  517.       ELSE IF vitesse=2400 THEN vitess := 5
  518.       ELSE IF vitesse=4800 THEN vitess := 6
  519.       ELSE IF vitesse=9600 THEN vitess := 7
  520.       ELSE IF vitesse=19200 THEN vitess := 8
  521.       ELSE IF vitesse=28800 THEN vitess := 9
  522.       ELSE IF vitesse=38400 THEN vitess := 10
  523.       ELSE IF vitesse=57600 THEN vitess := 11
  524.       ELSE IF vitesse=115200 THEN vitess := 12
  525.       ELSE Exit;
  526.     bl := descripteur_format;
  527.     bh := vitess;
  528.     dx := CommPort;
  529.     ah := $0B;
  530.     IF RS_accessible THEN
  531.     BEGIN
  532.       Intr($14,Dos.Registers(reg88));
  533.       Taille_InBuff := bx;
  534.       Taille_OutBuff := cx;
  535.       Init_Port := 0;
  536.     END
  537.     ELSE Init_Port := 2;
  538.   END
  539. END;
  540.  
  541.  
  542. PROCEDURE Init_status(VAR Format: WORD);
  543. VAR
  544.   Mem_Variable : ARRAY[1..3] OF BYTE        ;
  545. BEGIN
  546.   IF RS_accessible THEN
  547.   BEGIN
  548.     WITH reg88 DO
  549.     BEGIN
  550.       es := Seg(Mem_Variable[1]);
  551.       di := Ofs(Mem_Variable[1]);
  552.       dx := CommPort;
  553.       ah := $0C;
  554.       Intr($14,Dos.Registers(reg88))
  555.     END;
  556.     Format := (Mem_Variable[2]*256) + Mem_Variable[3];
  557.   END
  558. END;
  559.  
  560.  
  561. FUNCTION Reset_Init_status(Format: WORD): BYTE;
  562. BEGIN
  563.   WITH reg88 DO
  564.   BEGIN
  565.     bx := Format;
  566.     dx := CommPort;
  567.     ah := $0B;
  568.     IF RS_accessible THEN
  569.     BEGIN
  570.       Intr($14,Dos.Registers(reg88));
  571.       IF ah=0 THEN Reset_Init_status := 0
  572.         ELSE Reset_Init_status := 1;
  573.     END
  574.     ELSE Reset_Init_status := 2;
  575.   END
  576. END;
  577.  
  578.  
  579. PROCEDURE Flush_buffers;
  580. BEGIN
  581.   IF RS_accessible THEN
  582.   BEGIN
  583.     WITH reg88 DO
  584.     BEGIN
  585.       dx := CommPort;
  586.       ah := $0E;
  587.       Intr($14,Dos.Registers(reg88));
  588.     END;
  589.   END
  590. END;
  591.  
  592.  
  593. PROCEDURE Flush_InBuff;
  594. BEGIN
  595.   IF RS_accessible THEN
  596.   BEGIN
  597.     WITH reg88 DO
  598.     BEGIN
  599.       dx := CommPort;
  600.       ah := $0F;
  601.       Intr($14,Dos.Registers(reg88));
  602.     END;
  603.   END
  604. END;
  605.  
  606.  
  607. PROCEDURE Flush_OutBuff;
  608. BEGIN
  609.   IF RS_accessible THEN
  610.   BEGIN
  611.     WITH reg88 DO
  612.     BEGIN
  613.       dx := CommPort;
  614.       ah := $10;
  615.       Intr($14,Dos.Registers(reg88));
  616.     END;
  617.   END
  618. END;
  619.  
  620.  
  621. PROCEDURE ResetPort_and_TimMAX(RdTim_MAX: BYTE; VAR Old_RdTim_MAX: BYTE;
  622.           WrTim_MAX: BYTE; VAR Old_WrTim_MAX: BYTE);
  623. BEGIN
  624.   IF RS_accessible THEN
  625.   BEGIN
  626.     WITH reg88 DO
  627.     BEGIN
  628.       ah := $11;
  629.       bh := RdTim_MAX;
  630.       bl := WrTim_MAX;
  631.       dx := CommPort;
  632.       Intr($14,Dos.Registers(reg88));
  633.       Old_RdTim_MAX := bh;
  634.       Old_WrTim_MAX := bl
  635.     END;
  636.   END
  637. END;
  638.  
  639.  
  640. PROCEDURE Status_Trait_Erreurs(VAR mode: BYTE; VAR codeEr, codeBk: CHAR);
  641. BEGIN
  642.   IF RS_accessible THEN
  643.   BEGIN
  644.     WITH reg88 DO
  645.     BEGIN
  646.       ah := $12;
  647.       dx := CommPort;
  648.       Intr($14,Dos.Registers(reg88));
  649.       mode := al;
  650.       codeEr := Chr(bl);
  651.       codeBk := Chr(bh);
  652.     END;
  653.   END
  654. END;
  655.  
  656.  
  657. FUNCTION Def_Trait_Erreurs(mode: BYTE; code: CHAR): BYTE;
  658. BEGIN
  659.   IF RS_accessible THEN
  660.   BEGIN
  661.     WITH reg88 DO
  662.     BEGIN
  663.       al := mode;
  664.       bl := Ord(code);
  665.       dx := CommPort;
  666.       ah := $13;
  667.       Intr($14,Dos.Registers(reg88));
  668.       Def_Trait_Erreurs := ah
  669.     END;
  670.   END
  671. END;
  672.  
  673.  
  674. FUNCTION Change_com_port(Num_port: BYTE): BYTE;
  675. BEGIN
  676.   IF RS_accessible THEN
  677.   BEGIN
  678.     WITH reg88 DO
  679.     BEGIN
  680.       CommPort := Num_port;
  681.       dx := CommPort;
  682.       ah := $08;
  683.       Intr($14,Dos.Registers(reg88));
  684.       Change_com_port := ah
  685.     END;
  686.   END
  687. END;
  688.  
  689.  
  690. FUNCTION Attend_Buff_ems_vide(Temps_maxi: BYTE): BOOLEAN;
  691. BEGIN
  692.   IF RS_accessible THEN
  693.   BEGIN
  694.     WITH reg88 DO
  695.     BEGIN
  696.       ah := $1B;
  697.       al := Temps_maxi;
  698.       dx := CommPort;
  699.       Intr($14,Dos.Registers(reg88));
  700.       IF ah=4 THEN Attend_Buff_ems_vide := FALSE
  701.         ELSE Attend_Buff_ems_vide := TRUE;
  702.     END;
  703.   END
  704. END;
  705.  
  706.  
  707. FUNCTION CheckBufferIn(VAR nb_a_lire: WORD): BOOLEAN;
  708. BEGIN
  709.   IF RS_accessible THEN
  710.   BEGIN
  711.     WITH reg88 DO
  712.     BEGIN
  713.       ah := $1C;
  714.       dx := CommPort;
  715.       Intr($14,Dos.Registers(reg88));
  716.       nb_a_lire := cx;
  717.       IF (ah=0) AND (al=0) THEN CheckBufferIn := TRUE
  718.         ELSE CheckBufferIn := FALSE;
  719.     END;
  720.   END
  721.   ELSE CheckBufferIn := FALSE;
  722. END;
  723.  
  724.  
  725. FUNCTION CheckBufferOut(VAR place_libre: WORD): BOOLEAN;
  726. BEGIN
  727.   IF RS_accessible THEN
  728.   BEGIN
  729.     WITH reg88 DO
  730.     BEGIN
  731.       ah := $1D;
  732.       dx := CommPort;
  733.       Intr($14,Dos.Registers(reg88));
  734.       place_libre := cx;
  735.       IF (ah=0) AND (al=0) THEN CheckBufferOut := TRUE
  736.         ELSE CheckBufferOut := FALSE;
  737.     END;
  738.   END
  739.   ELSE CheckBufferOut := FALSE;
  740. END;
  741.  
  742.  
  743. FUNCTION ReadSerie(VAR c: CHAR; nombre: WORD; VAR Nb_received: WORD): BYTE;
  744. BEGIN
  745.   IF RS_accessible THEN
  746.   BEGIN
  747.     WITH reg88 DO
  748.     BEGIN
  749.       ah := $14;
  750.       es := Seg(c);
  751.       di := Ofs(c);
  752.       cx := nombre;
  753.       dx := CommPort;
  754.       Intr($14,Dos.Registers(reg88));
  755.       Nb_received := cx;
  756.       ReadSerie := ah
  757.     END;
  758.   END
  759. END;
  760.  
  761.  
  762. FUNCTION WriteSerie(VAR c: CHAR; nombre: WORD; VAR Nb_written: WORD): BYTE;
  763. BEGIN
  764.   IF RS_accessible THEN
  765.   BEGIN
  766.     WITH reg88 DO
  767.     BEGIN
  768.       ah := $15;
  769.       es := Seg(c);
  770.       di := Ofs(c);
  771.       cx := nombre;
  772.       dx := CommPort;
  773.       Intr($14,Dos.Registers(reg88));
  774.       Nb_written := cx;
  775.       WriteSerie := ah
  776.     END;
  777.   END
  778. END;
  779.  
  780.  
  781. FUNCTION ReadCarSerie(VAR c: CHAR): BYTE;
  782. BEGIN
  783.   IF RS_accessible THEN
  784.   BEGIN
  785.     WITH reg88 DO
  786.     BEGIN
  787.       ah := $16;
  788.       dx := CommPort;
  789.       Intr($14,Dos.Registers(reg88));
  790.       c := Chr(al);
  791.       ReadCarSerie := ah
  792.     END;
  793.   END
  794. END;
  795.  
  796.  
  797. FUNCTION WriteCarSerie(c: CHAR): BYTE;
  798. BEGIN
  799.   IF RS_accessible THEN
  800.   BEGIN
  801.     WITH reg88 DO
  802.     BEGIN
  803.       ah := $17;
  804.       al := Ord(c);
  805.       dx := CommPort;
  806.       Intr($14,Dos.Registers(reg88));
  807.       WriteCarSerie := ah
  808.     END;
  809.   END
  810. END;
  811.  
  812.  
  813. FUNCTION Peek_rcp(VAR c: CHAR): BYTE;
  814. BEGIN
  815.   IF RS_accessible THEN
  816.   BEGIN
  817.     WITH reg88 DO
  818.     BEGIN
  819.       ah := $18;
  820.       dx := CommPort;
  821.       Intr($14,Dos.Registers(reg88));
  822.       c := Chr(al);
  823.       Peek_rcp := ah
  824.     END;
  825.   END
  826. END;
  827.  
  828.  
  829. FUNCTION Poke_rcp(c: CHAR): BYTE;
  830. BEGIN
  831.   IF RS_accessible THEN
  832.   BEGIN
  833.     WITH reg88 DO
  834.     BEGIN
  835.       ah := $19;
  836.       al := Ord(c);
  837.       dx := CommPort;
  838.       Intr($14,Dos.Registers(reg88));
  839.       Poke_rcp := ah
  840.     END;
  841.   END
  842. END;
  843.  
  844.  
  845. FUNCTION WriteCmde(VAR Cmde: CHAR; nombre: BYTE; UseDTR: BOOLEAN): BYTE;
  846. BEGIN
  847.   IF RS_accessible THEN
  848.   BEGIN
  849.     WITH reg88 DO
  850.     BEGIN
  851.       ah := $1A;
  852.       es := Seg(Cmde);
  853.       di := Ofs(Cmde);
  854.       al := nombre;
  855.       IF UseDTR THEN bh := 1 ELSE bh := 0;
  856.       dx := CommPort;
  857.       Intr($14,Dos.Registers(reg88));
  858.       WriteCmde := ah
  859.     END;
  860.   END
  861. END;
  862.  
  863.  
  864. PROCEDURE Etat_du_Modem(VAR Voie_active: CHAR; VAR Pret, Clear_to_send,
  865.           Sonnerie, Porteuse, Changements: BOOLEAN; VAR deltaDSR, deltaCTS,
  866.           deltaRI, deltaDCD: BYTE);
  867. VAR
  868.   Mem_Variable : ARRAY[1..10] OF BYTE       ;
  869.   voie_num     : CHAR absolute Mem_Variable ;
  870. BEGIN
  871.   IF RS_accessible THEN
  872.   BEGIN
  873.     WITH reg88 DO
  874.     BEGIN
  875.       es := Seg(Mem_Variable[1]);
  876.       di := Ofs(Mem_Variable[1]);
  877.       dx := CommPort;
  878.       ah := $20;
  879.       al := 0;
  880.       Intr($14,Dos.Registers(reg88))
  881.     END;
  882.     Mem_Variable[1] := Mem_Variable[1] + $31;
  883.     Voie_active := voie_num;
  884.     IF Mem_Variable[2]=1 THEN Pret := TRUE
  885.       ELSE Pret := FALSE;
  886.     IF Mem_Variable[3]=1 THEN Clear_to_send := TRUE
  887.       ELSE Clear_to_send := FALSE;
  888.     IF Mem_Variable[4]=1 THEN Sonnerie := TRUE
  889.       ELSE Sonnerie := FALSE;
  890.     IF Mem_Variable[5]=1 THEN Porteuse := TRUE
  891.       ELSE Porteuse := FALSE;
  892.     IF Mem_Variable[6]=1 THEN Changements := TRUE
  893.       ELSE Changements := FALSE;
  894.     deltaDSR := Mem_Variable[7];
  895.     deltaCTS := Mem_Variable[8];
  896.     deltaRI := Mem_Variable[9];
  897.     deltaDCD := Mem_Variable[10];
  898.   END
  899. END;
  900.  
  901.  
  902. PROCEDURE Set_DTR;
  903. BEGIN
  904.   IF RS_accessible THEN
  905.   BEGIN
  906.     WITH reg88 DO
  907.     BEGIN
  908.       di := $01;
  909.       dx := CommPort;
  910.       ah := $20;
  911.       al := 1;
  912.       Intr($14,Dos.Registers(reg88))
  913.     END;
  914.   END
  915. END;
  916.  
  917.  
  918. PROCEDURE Clear_DTR;
  919. BEGIN
  920.   IF RS_accessible THEN
  921.   BEGIN
  922.     WITH reg88 DO
  923.     BEGIN
  924.       di := $FE;
  925.       dx := CommPort;
  926.       ah := $20;
  927.       al := 2;
  928.       Intr($14,Dos.Registers(reg88))
  929.     END;
  930.   END
  931. END;
  932.  
  933.  
  934. PROCEDURE Set_RTS;
  935. BEGIN
  936.   IF RS_accessible THEN
  937.   BEGIN
  938.     WITH reg88 DO
  939.     BEGIN
  940.       di := $02;
  941.       dx := CommPort;
  942.       ah := $20;
  943.       al := 1;
  944.       Intr($14,Dos.Registers(reg88))
  945.     END;
  946.   END
  947. END;
  948.  
  949.  
  950. PROCEDURE Clear_RTS;
  951. BEGIN
  952.   IF RS_accessible THEN
  953.   BEGIN
  954.     WITH reg88 DO
  955.     BEGIN
  956.       di := $FD;
  957.       dx := CommPort;
  958.       ah := $20;
  959.       al := 2;
  960.       Intr($14,Dos.Registers(reg88))
  961.     END;
  962.   END
  963. END;
  964.  
  965.  
  966. PROCEDURE Set_OUT1;
  967. BEGIN
  968.   IF RS_accessible THEN
  969.   BEGIN
  970.     WITH reg88 DO
  971.     BEGIN
  972.       di := $04;
  973.       dx := CommPort;
  974.       ah := $20;
  975.       al := 1;
  976.       Intr($14,Dos.Registers(reg88))
  977.     END;
  978.   END
  979. END;
  980.  
  981.  
  982. PROCEDURE Clear_OUT1;
  983. BEGIN
  984.   IF RS_accessible THEN
  985.   BEGIN
  986.     WITH reg88 DO
  987.     BEGIN
  988.       di := $FB;
  989.       dx := CommPort;
  990.       ah := $20;
  991.       al := 2;
  992.       Intr($14,Dos.Registers(reg88))
  993.     END;
  994.   END
  995. END;
  996.  
  997.  
  998. PROCEDURE Send_break(duree: BYTE);
  999. BEGIN
  1000.   IF RS_accessible THEN
  1001.   BEGIN
  1002.     reg88.bl := duree;
  1003.     reg88.ah := $1E;
  1004.     reg88.dx := CommPort;
  1005.     Intr($14,Dos.Registers(reg88))
  1006.   END;
  1007. END;
  1008.  
  1009.  
  1010. FUNCTION Errors_Report(VAR Buff_overflow, Engorgement, Parite,
  1011.          Stop_bit, Break_it: BYTE): BOOLEAN;
  1012. VAR
  1013.   Mem_Variable : ARRAY[1..5] OF BYTE ;
  1014. BEGIN
  1015.   IF RS_accessible THEN
  1016.   BEGIN
  1017.     WITH reg88 DO
  1018.     BEGIN
  1019.       es := Seg(Mem_Variable[1]);
  1020.       di := Ofs(Mem_Variable[1]);
  1021.       dx := CommPort;
  1022.       ah := $1F;
  1023.       Intr($14,Dos.Registers(reg88))
  1024.     END;
  1025.     Buff_overflow := Mem_Variable[1];
  1026.     Engorgement := Mem_Variable[2];
  1027.     Parite := Mem_Variable[3];
  1028.     Stop_bit := Mem_Variable[4];
  1029.     Break_it := Mem_Variable[5];
  1030.     IF (reg88.al=0) THEN Errors_Report := FALSE
  1031.       ELSE Errors_Report := TRUE;
  1032.   END
  1033. END;
  1034.  
  1035.  
  1036. FUNCTION Port_Free: BOOLEAN;
  1037. BEGIN
  1038.   IF RS_accessible THEN
  1039.   BEGIN
  1040.     WITH reg88 DO
  1041.     BEGIN
  1042.       ah := $25;
  1043.       dx := CommPort;
  1044.       Intr($14,Dos.Registers(reg88))
  1045.     END;
  1046.     IF (reg88.al=0) THEN Port_Free := FALSE
  1047.       ELSE Port_Free := TRUE;
  1048.   END
  1049. END;
  1050.  
  1051.  
  1052. FUNCTION HandShake_Status(Proto_type: BYTE;VAR SendEnabled: BOOLEAN): BYTE;
  1053. BEGIN
  1054.   IF RS_accessible THEN
  1055.   BEGIN
  1056.     WITH reg88 DO
  1057.     BEGIN
  1058.       ah := $21;
  1059.       al := Proto_type;
  1060.       dx := CommPort;
  1061.       Intr($14,Dos.Registers(reg88))
  1062.     END;
  1063.     IF (reg88.di=0) THEN SendEnabled := FALSE
  1064.       ELSE SendEnabled := TRUE;
  1065.     HandShake_status := reg88.al;
  1066.   END
  1067. END;
  1068.  
  1069.  
  1070. PROCEDURE HandShake_Setup(Proto_type: BYTE; state: BYTE);
  1071. BEGIN
  1072.   IF RS_accessible THEN
  1073.   BEGIN
  1074.     WITH reg88 DO
  1075.     BEGIN
  1076.       ah := $22;
  1077.       al := Proto_type;
  1078.       state := state AND $DF;
  1079.       IF state IN [Inactif,Local,Eloigne,Bilateral] THEN
  1080.         bh := state
  1081.       ELSE bh := 0;
  1082.       dx := CommPort;
  1083.       Intr($14,Dos.Registers(reg88))
  1084.     END;
  1085.   END
  1086. END;
  1087.  
  1088.  
  1089. FUNCTION XonoffShaking_Status(VAR SendEnabled: BOOLEAN;
  1090.          VAR Nb_Xoff: BYTE): BYTE;
  1091. VAR
  1092.   Mem_Variable : ARRAY[1..5] OF BYTE ;
  1093. BEGIN
  1094.   IF RS_accessible THEN
  1095.   BEGIN
  1096.     WITH reg88 DO
  1097.     BEGIN
  1098.       es := Seg(Mem_Variable[1]);
  1099.       di := Ofs(Mem_Variable[1]);
  1100.       dx := CommPort;
  1101.       ah := $23;
  1102.       Intr($14,Dos.Registers(reg88))
  1103.     END;
  1104.     Xon := Mem_Variable[1];
  1105.     Xoff := Mem_Variable[2];
  1106.     Nb_Xoff := Mem_Variable[3];
  1107.     IF (Mem_Variable[4]=Xon) THEN SendEnabled := TRUE
  1108.       ELSE SendEnabled := FALSE;
  1109.     XonoffShaking_Status := Mem_Variable[5];
  1110.   END
  1111. END;
  1112.  
  1113.  
  1114. PROCEDURE XonoffShaking_Setup(state: BYTE);
  1115. BEGIN
  1116.   IF RS_accessible THEN
  1117.   BEGIN
  1118.     WITH reg88 DO
  1119.     BEGIN
  1120.       ah := $24;
  1121.       state := state AND $DF;
  1122.       IF state IN [Inactif,Local,Eloigne,Bilateral] THEN
  1123.         al := state
  1124.       ELSE al := 0;
  1125.       bh := Xon;
  1126.       bl := Xoff;
  1127.       dx := CommPort;
  1128.       Intr($14,Dos.Registers(reg88))
  1129.     END;
  1130.   END
  1131. END;
  1132.  
  1133.  
  1134. (* Define here any local variable you need for your user-routine: *)
  1135. (* VAR <.....>                                                    *)
  1136. PROCEDURE Routine; INTERRUPT;
  1137. (* !! ATTENTION !!  DO NOT DEFINE ANY VARIABLE HERE *)
  1138. BEGIN
  1139.   (* Install here the routine to be called by the driver. *)
  1140.   (* ... *)
  1141.   (* The following special code MUST NOT BE CHANGED !... *)
  1142.   INLINE($89/$EC (* mov sp,bp *)
  1143.    /$5D          (* pop bp    *)
  1144.    /$07          (* pop es    *)
  1145.    /$1F          (* pop ds    *)
  1146.    /$5F          (* pop di    *)
  1147.    /$5E          (* pop si    *)
  1148.    /$5A          (* pop dx    *)
  1149.    /$59          (* pop cx    *)
  1150.    /$5B          (* pop bx    *)
  1151.    /$58          (* pop ax    *)
  1152.    /$CB)         (* retf      *)
  1153. END;
  1154. PROCEDURE Set_routine(VAR Utilise: BOOLEAN; VAR Segment,Offset: WORD);
  1155. BEGIN
  1156.   IF RS_accessible THEN
  1157.   BEGIN
  1158.     WITH reg88 DO
  1159.     BEGIN
  1160.       ah := $26;
  1161.       es := Seg(Routine);
  1162.       di := Ofs(Routine);
  1163.       dx := CommPort;
  1164.       Intr($14,Dos.Registers(reg88));
  1165.       Utilise := (al=1);
  1166.       Segment := es;
  1167.       Offset := di
  1168.     END;
  1169.   END
  1170. END;
  1171.  
  1172.  
  1173. PROCEDURE Reset_routine(Segment,Offset: WORD);
  1174. BEGIN
  1175.   IF RS_accessible THEN
  1176.   BEGIN
  1177.     WITH reg88 DO
  1178.     BEGIN
  1179.       ah := $26;
  1180.       es := Segment;
  1181.       di := Offset;
  1182.       dx := CommPort;
  1183.       Intr($14,Dos.Registers(reg88))
  1184.     END;
  1185.   END
  1186. END;
  1187.  
  1188.  
  1189. PROCEDURE Unset_routine;
  1190. BEGIN
  1191.   IF RS_accessible THEN
  1192.   BEGIN
  1193.     WITH reg88 DO
  1194.     BEGIN
  1195.       ah := $27;
  1196.       dx := CommPort;
  1197.       Intr($14,Dos.Registers(reg88))
  1198.     END;
  1199.   END
  1200. END;
  1201.  
  1202.  
  1203. PROCEDURE Err_Routine; INTERRUPT;
  1204. (* !! ATTENTION !!  DO NOT USE ANY LOCAL VARIABLE TO MAKE THIS ROUTINE *)
  1205. (* THAT MUST BE FULLY RE-ENTRANT...                                    *)
  1206. BEGIN
  1207.   (* Install here the function to manage the Int. 14h errors.   *)
  1208.   (* Never call the DOS interrupt 21h !...                      *)
  1209.   (* "reg88.dx" gives you the port number eventually designated *)
  1210.   (* when the function 14h (making the error) has been called...*)
  1211.   (* ... *)
  1212.   (* The following special code MUST NOT BE CHANGED !... *)
  1213.   INLINE($89/$EC (* mov sp,bp *)
  1214.    /$5D          (* pop bp    *)
  1215.    /$07          (* pop es    *)
  1216.    /$1F          (* pop ds    *)
  1217.    /$5F          (* pop di    *)
  1218.    /$5E          (* pop si    *)
  1219.    /$5A          (* pop dx    *)
  1220.    /$59          (* pop cx    *)
  1221.    /$5B          (* pop bx    *)
  1222.    /$58          (* pop ax    *)
  1223.    /$CB)         (* retf      *)
  1224. END;
  1225. PROCEDURE Set_err_routine(VAR Utilise: BOOLEAN; VAR Segment,Offset: WORD);
  1226. BEGIN
  1227.   IF RS_accessible THEN
  1228.   BEGIN
  1229.     WITH reg88 DO
  1230.     BEGIN
  1231.       ah := $28;
  1232.       es := Seg(Err_Routine);
  1233.       di := Ofs(Err_Routine);
  1234.       Intr($14,Dos.Registers(reg88));
  1235.       Utilise := (al=1);
  1236.       Segment := es;
  1237.       Offset := di
  1238.     END;
  1239.   END
  1240. END;
  1241.  
  1242.  
  1243. PROCEDURE Reset_err_routine(Segment,Offset: WORD);
  1244. BEGIN
  1245.   IF RS_accessible THEN
  1246.   BEGIN
  1247.     WITH reg88 DO
  1248.     BEGIN
  1249.       ah := $28;
  1250.       es := Segment;
  1251.       di := Offset;
  1252.       Intr($14,Dos.Registers(reg88))
  1253.     END;
  1254.   END
  1255. END;
  1256.  
  1257.  
  1258. PROCEDURE Unset_err_routine;
  1259. BEGIN
  1260.   IF RS_accessible THEN
  1261.   BEGIN
  1262.     WITH reg88 DO
  1263.     BEGIN
  1264.       ah := $29;
  1265.       Intr($14,Dos.Registers(reg88))
  1266.     END;
  1267.   END
  1268. END;
  1269.  
  1270.  
  1271. PROCEDURE Verrouille;
  1272. BEGIN
  1273.   IF RS_accessible THEN
  1274.   BEGIN
  1275.     WITH reg88 DO
  1276.     BEGIN
  1277.       ah := $2A;
  1278.       al := 1;
  1279.       bl := 1;
  1280.       Intr($14,Dos.Registers(reg88))
  1281.     END;
  1282.   END
  1283. END;
  1284.  
  1285.  
  1286. PROCEDURE Deverrouille;
  1287. BEGIN
  1288.   IF RS_accessible THEN
  1289.   BEGIN
  1290.     WITH reg88 DO
  1291.     BEGIN
  1292.       ah := $2A;
  1293.       al := 1;
  1294.       bl := 0;
  1295.       Intr($14,Dos.Registers(reg88))
  1296.     END;
  1297.   END
  1298. END;
  1299.  
  1300.  
  1301. FUNCTION GetDeviceName: BYTE;
  1302. VAR
  1303.   Nom : STRING[8] ;
  1304. BEGIN
  1305.   IF RS_accessible THEN
  1306.   BEGIN
  1307.     WITH reg88 DO
  1308.     BEGIN
  1309.       ah := $2B;
  1310.       es := Seg(Nom[1]);
  1311.       di := Ofs(Nom[1]);
  1312.       Intr($14,Dos.Registers(reg88));
  1313.       IF ah=0 THEN NomDevice := Nom;
  1314.       GetDeviceName := ah
  1315.     END;
  1316.   END
  1317. END;
  1318.  
  1319.  
  1320. FUNCTION GetPortDevice: BYTE;
  1321. BEGIN
  1322.   IF RS_accessible THEN
  1323.   BEGIN
  1324.     WITH reg88 DO
  1325.     BEGIN
  1326.       al := 0;
  1327.       ah := $2C;
  1328.       Intr($14,Dos.Registers(reg88));
  1329.       IF ah=0 THEN GetPortDevice := al
  1330.         ELSE GetPortDevice := ah
  1331.     END;
  1332.   END
  1333. END;
  1334.  
  1335.  
  1336. FUNCTION ResetPortDevice: BYTE;
  1337. BEGIN
  1338.   IF RS_accessible THEN
  1339.   BEGIN
  1340.     WITH reg88 DO
  1341.     BEGIN
  1342.       al := 1;
  1343.       ah := $2C;
  1344.       dx := CommPort;
  1345.       Intr($14,Dos.Registers(reg88));
  1346.       ResetPortDevice := ah
  1347.     END;
  1348.   END
  1349. END;
  1350.  
  1351.  
  1352. FUNCTION EmulBIOS: BOOLEAN;
  1353. BEGIN
  1354.   IF RS_accessible THEN
  1355.   BEGIN
  1356.     WITH reg88 DO
  1357.     BEGIN
  1358.       al := 0;
  1359.       ah := $2D;
  1360.       Intr($14,Dos.Registers(reg88));
  1361.       IF al=1 THEN EmulBIOS := TRUE ELSE EmulBIOS := FALSE
  1362.     END;
  1363.   END
  1364. END;
  1365.  
  1366.  
  1367. PROCEDURE SetEmulBIOS(status: BOOLEAN);
  1368. BEGIN
  1369.   IF RS_accessible THEN
  1370.   BEGIN
  1371.     WITH reg88 DO
  1372.     BEGIN
  1373.       al := 1;
  1374.       ah := $2D;
  1375.       IF status THEN bl := 1 ELSE bl := 0;
  1376.       Intr($14,Dos.Registers(reg88))
  1377.     END;
  1378.   END
  1379. END;
  1380.  
  1381.  
  1382. FUNCTION OrdiType: BYTE;
  1383. BEGIN
  1384.   IF RS_accessible THEN
  1385.   BEGIN
  1386.     WITH reg88 DO
  1387.     BEGIN
  1388.       al := 0;
  1389.       ah := $2E;
  1390.       Intr($14,Dos.Registers(reg88));
  1391.       OrdiType := bl
  1392.     END;
  1393.   END
  1394. END;
  1395.  
  1396.  
  1397. PROCEDURE SetOrdiType(OrdiType: BYTE);
  1398. BEGIN
  1399.   IF RS_accessible THEN
  1400.   BEGIN
  1401.     WITH reg88 DO
  1402.     BEGIN
  1403.       al := 1;
  1404.       ah := $2E;
  1405.       bl := OrdiType;
  1406.       Intr($14,Dos.Registers(reg88))
  1407.     END;
  1408.   END
  1409. END;
  1410.  
  1411.  
  1412. FUNCTION Open_COMM: WORD;
  1413. BEGIN
  1414.   IF NOT COMM_ouvert THEN
  1415.   BEGIN
  1416.     WITH reg88 DO
  1417.     BEGIN
  1418.       ah := $3D;
  1419.       ds := Seg(NomDevice[1]);
  1420.       dx := Ofs(NomDevice[1]);
  1421.       al := 2;
  1422.       msdos(Dos.Registers(reg88));
  1423.       IF (Flags AND 1)<>0 THEN
  1424.         Open_COMM := ax
  1425.       ELSE
  1426.       BEGIN
  1427.         Open_COMM          := 0;
  1428.         handler_voie_serie := ax;
  1429.         COMM_ouvert        := TRUE
  1430.       END;
  1431.     END
  1432.   END;
  1433. END;
  1434.  
  1435.  
  1436. FUNCTION Close_COMM: INTEGER;
  1437. BEGIN
  1438.   IF COMM_ouvert THEN
  1439.   BEGIN
  1440.     WITH reg88 DO
  1441.     BEGIN
  1442.       ah := $3E;
  1443.       bx := handler_voie_serie;
  1444.       msdos(Dos.Registers(reg88));
  1445.       IF (Flags AND 1)<>0 THEN
  1446.         Close_COMM := ax
  1447.       ELSE
  1448.       BEGIN
  1449.         Close_COMM := 0;
  1450.         COMM_ouvert := FALSE
  1451.       END;
  1452.     END;
  1453.   END
  1454.   ELSE Close_COMM := -1
  1455. END;
  1456.  
  1457.  
  1458. FUNCTION IOStream_READ(VAR Voie_active: CHAR;VAR Format: WORD; VAR RTS_type,
  1459.          DTR_type, RI_type, DCD_type, OUT1_type, Xonoff_type: CHAR): BOOLEAN;
  1460. VAR
  1461.   buff : ARRAY[1..11] OF BYTE ;
  1462. BEGIN
  1463.   IF COMM_ouvert THEN
  1464.   BEGIN
  1465.     WITH reg88 DO
  1466.     BEGIN
  1467.       ah := $44;
  1468.       al := 2;
  1469.       cx := 11;
  1470.       ds := Seg(buff[1]);
  1471.       dx := Ofs(buff[1]);
  1472.       bx := handler_voie_serie;
  1473.       msdos(Dos.Registers(reg88));
  1474.       IF (Flags AND 1)=0 THEN
  1475.       BEGIN
  1476.         Voie_active := Chr(buff[1]+1);
  1477.         Format := (buff[2] * 256) + buff[3];
  1478.         RTS_type := Chr(buff[4]);
  1479.         DTR_type := Chr(buff[5]);
  1480.         RI_type := Chr(buff[6]);
  1481.         DCD_type := Chr(buff[7]);
  1482.         OUT1_type := Chr(buff[8]);
  1483.         Xonoff_type := Chr(buff[9]);
  1484.         Xon := buff[10];
  1485.         Xoff := buff[11];
  1486.         IOStream_READ := FALSE;
  1487.       END
  1488.       ELSE IOStream_READ := TRUE;
  1489.     END
  1490.   END;
  1491. END;
  1492.  
  1493.  
  1494. FUNCTION IOStream_WRITE(VAR Voie_active: CHAR;VAR Format: WORD; VAR RTS_type,
  1495.          DTR_type, RI_type, DCD_type, OUT1_type, Xonoff_type: CHAR): BOOLEAN;
  1496. VAR
  1497.   buff : ARRAY[1..11] OF BYTE ;
  1498. BEGIN
  1499.   IF COMM_ouvert THEN
  1500.   BEGIN
  1501.     WITH reg88 DO
  1502.     BEGIN
  1503.       buff[1] := Ord(Voie_active)-$30-1;
  1504.       ax := Format;
  1505.       buff[2] := ah;
  1506.       buff[3] := al;
  1507.       buff[4] := Ord(RTS_type);
  1508.       buff[5] := Ord(DTR_type);
  1509.       buff[6] := Ord(RI_type);
  1510.       buff[7] := Ord(DCD_type);
  1511.       buff[8] := Ord(OUT1_type);
  1512.       buff[9] := Ord(Xonoff_type);
  1513.       buff[10] := Xon;
  1514.       buff[11] := Xoff;
  1515.       ah := $44;
  1516.       al := 3;
  1517.       cx := 11;
  1518.       ds := Seg(buff[1]);
  1519.       dx := Ofs(buff[1]);
  1520.       bx := handler_voie_serie;
  1521.       msdos(Dos.Registers(reg88));
  1522.       IF (Flags AND 1)=0 THEN IOStream_WRITE := FALSE
  1523.         ELSE IOStream_WRITE := TRUE;
  1524.     END;
  1525.   END
  1526. END;
  1527.  
  1528.  
  1529. FUNCTION CheckCOMMIn: BOOLEAN;
  1530. BEGIN
  1531.   IF COMM_ouvert THEN
  1532.   BEGIN
  1533.     WITH reg88 DO
  1534.     BEGIN
  1535.       ah := $44;
  1536.       al := 6;
  1537.       bx := handler_voie_serie;
  1538.       msdos(Dos.Registers(reg88));
  1539.       IF al=0 THEN CheckCOMMIn := TRUE
  1540.         ELSE CheckCOMMIn := FALSE;
  1541.     END;
  1542.   END
  1543.   ELSE CheckCOMMIn := FALSE;
  1544. END;
  1545.  
  1546.  
  1547. FUNCTION CheckCOMMOut: BOOLEAN;
  1548. BEGIN
  1549.   IF COMM_ouvert THEN
  1550.   BEGIN
  1551.     WITH reg88 DO
  1552.     BEGIN
  1553.       ah := $44;
  1554.       al := 7;
  1555.       bx := handler_voie_serie;
  1556.       msdos(Dos.Registers(reg88));
  1557.       IF al=0 THEN CheckCOMMOut := TRUE
  1558.         ELSE CheckCOMMOut := FALSE;
  1559.     END;
  1560.   END
  1561.   ELSE CheckCOMMOut := FALSE;
  1562. END;
  1563.  
  1564.  
  1565. FUNCTION ReadCOMM(VAR c: CHAR; nombre: WORD): INTEGER;
  1566. BEGIN
  1567.   IF COMM_ouvert THEN
  1568.   BEGIN
  1569.     WITH reg88 DO
  1570.     BEGIN
  1571.       ah := $3F;
  1572.       bx := handler_voie_serie;
  1573.       cx := nombre;
  1574.       ds := Seg(c);
  1575.       dx := Ofs(c);
  1576.       msdos(Dos.Registers(reg88));
  1577.       IF (Flags AND 1)<>0 THEN
  1578.         ReadCOMM := ax
  1579.       ELSE
  1580.         IF ax<>0 THEN ReadCOMM := 0
  1581.           ELSE ReadCOMM := -1;
  1582.     END;
  1583.   END
  1584. END;
  1585.  
  1586.  
  1587. FUNCTION WriteCOMM(VAR c: CHAR; nombre: WORD): INTEGER;
  1588. BEGIN
  1589.   IF COMM_ouvert THEN
  1590.   BEGIN
  1591.     WITH reg88 DO
  1592.     BEGIN
  1593.       ah := $40;
  1594.       bx := handler_voie_serie;
  1595.       ds := Seg(c);
  1596.       dx := Ofs(c);
  1597.       cx := nombre;
  1598.       msdos(Dos.Registers(reg88));
  1599.       IF (Flags AND 1)<>0 THEN
  1600.         WriteCOMM := ax
  1601.       ELSE
  1602.         IF ax<>0 THEN WriteCOMM := 0
  1603.           ELSE WriteCOMM := -1;
  1604.     END;
  1605.   END
  1606. END;
  1607.  
  1608.  
  1609. FUNCTION Check_STARCOMM_Present: BYTE;
  1610. VAR
  1611.   Check : BYTE ;
  1612. BEGIN
  1613.   Check := 0;
  1614.   WITH reg88 DO
  1615.   BEGIN
  1616.     ah := 6;
  1617.     al := 0;
  1618.     Intr($14,Dos.Registers(reg88));
  1619.     IF al<>0 THEN
  1620.     BEGIN
  1621.       RS_accessible := TRUE;
  1622.       Check := 1;
  1623.     END
  1624.     ELSE RS_accessible := FALSE
  1625.   END;
  1626.   IF RS_accessible THEN
  1627.     IF GetDeviceName=0 THEN Check := 2;
  1628.   Check_STARCOMM_Present := Check
  1629. END;
  1630.  
  1631.  
  1632. BEGIN
  1633.   COMM_ouvert := FALSE;              (* The DEVICE port is NOT open. *)
  1634.   type_driver := Check_STARCOMM_Present;
  1635.   IF type_driver<>0 THEN Get_Ports_Adresses
  1636. END.